import copy
import datetime
import json
import random
import threading
import time
from exception.api_exception import APIException
import model.model as ut
from utils.commit import submit_tx, submit_gg, submit_qualtrics, submit_wjw, submit_wjw_v2, submit_credamo
from utils.common.scheduler import scheduler
from dao import work_order_dao, topic_dao, work_order_extend_dao
from utils.commit.submit_wjx_v2 import do_submit, convert_data_to_submit_data
from enums.work_order_status_enum import WorkOrderStatusEnum
from utils.common.init_app import app
import traceback


def update_topic_info(item_topic: ut.Topic, status: int, submit_start_time, submit_end_time, request_res,
                      request_ip):
    """
    更新当前数据提交后的结果状态
    :param item_topic:
    :param status:
    :param submit_start_time: 提交开始时间
    :param submit_end_time: 提交结束时间
    :param request_res: 请求结果
    :param request_ip: 请求的ip地址
    :return:
    """
    item_topic.submitted = status
    item_topic.submit_start_time = submit_start_time
    item_topic.submit_end_time = submit_end_time
    item_topic.request_res = request_res
    item_topic.request_ip = request_ip
    topic_dao.batch_update_by_id([item_topic])
    return


def chinese_to_unicode(text):
    """将中文转成unicode"""
    return ''.join(f'\\u{ord(c):04x}' for c in text)


def send_item(data_id: int, sleep_time: int, db_title_arr, send_title_link, this_work_order_id: int,
              send_random_area: str, send_times: int):
    """
    发送每一条数据
    :param data_id: 这条数据在数据库中的id
    # :param cur_topic_id: 这条数据在数据库中的对象
    # :param send_data: 需要发送的数据
    :param sleep_time: 需要暂停的时间
    :param db_title_arr: 问卷所有标题对应的数据库中的标题内容
    :param send_title_link: 问卷的链接
    :param this_work_order_id: 工单id
    :param send_random_area: 标准区域的编码，全国是all
    :param send_times: 发送次数 大于等于5，则发送失败
    :return:
    """
    with app.app_context():
        cur_topic = topic_dao.search_by_id(data_id)
        app.logger.info('send_item提交数据，data_id:' + str(data_id) + ', this_work_order_id:' + str(this_work_order_id))
        if not cur_topic:
            return
        if cur_topic.submitted == 2:
            return  # 这份数据已发送完成，直接返回
        send_data = cur_topic.data
        # 1. 组装文件发送数据
        # 2. 发送问卷
        if send_times >= 5:  # 自动重试默认发送5次,5次之后直接失败
            # 修改这条数据为发送失败
            update_topic_info(cur_topic, -1, cur_topic.submit_start_time, int(time.time()),
                              cur_topic.request_res, cur_topic.request_ip)
            # 修改工单的状态为发送失败
            work_order_dao.modify_work_order_status(this_work_order_id, WorkOrderStatusEnum.SEND_ERROR.value)
            return
        else:
            t_start = int(time.time())
            request_str = ''
            ip_res = ''
            try:
                wo_topic_id = '%s_%s' % (str(this_work_order_id), str(data_id))  # 工单和这条数据的id
                if send_title_link.startswith('https://www.wenjuan.com'):  # 问卷网
                    if send_title_link.__contains__('/t/'):
                        send_title_link = send_title_link.split('/t/')[0] + '/s/' + send_title_link.split('/t/')[1]
                    submit_data = submit_wjw_v2.convert_data_to_submit_data(db_title_arr, json.loads(send_data),
                                                                            send_title_link, sleep_time)
                    # app.logger.debug(f'需要提交的答案{submit_data}')
                    request_res, ip_res = submit_wjw_v2.do_submit(send_random_area, send_title_link, submit_data,
                                                                  sleep_time,
                                                                  wo_topic_id)
                    request_str = request_res
                elif send_title_link.startswith('https://wj.qq.com'):  # 腾讯问卷
                    submit_data = submit_tx.convert_data_to_submit_data(db_title_arr, json.loads(send_data),
                                                                        send_title_link)
                    # app.logger.debug(f'需要提交的答案{submit_data}')
                    request_res, ip_res = submit_tx.do_submit(send_random_area, send_title_link, submit_data,
                                                              sleep_time,
                                                              wo_topic_id)
                    request_str = request_res
                elif send_title_link.startswith('https://docs.google.com'):  # 谷歌问卷
                    submit_data = submit_gg.convert_data_to_submit_data(db_title_arr, json.loads(send_data),
                                                                        send_title_link)
                    # app.logger.debug(f'需要提交的答案{submit_data}')
                    request_res, ip_res = submit_gg.do_submit(send_random_area, send_title_link, submit_data,
                                                              sleep_time,
                                                              wo_topic_id)
                    request_str = submit_gg.get_simple_result(request_res)
                elif 'qualtrics' in send_title_link or 'q.surveys.' in send_title_link:  # qualtrics问卷
                    thread_id = threading.get_ident()
                    db_title_arr_n = copy.deepcopy(db_title_arr)  # 用于分页情况下队列分批获取submit_data数据
                    db_res_arr = json.loads(send_data)
                    qo = submit_qualtrics.get_qsq(send_title_link, wo_topic_id, sleep_time, send_random_area)
                    request_res = None
                    try:
                        submit_data = submit_qualtrics.convert_data_to_submit_data(db_title_arr_n, db_res_arr, qo,
                                                                                   sleep_time)
                        request_res, ip_res = submit_qualtrics.do_submit(submit_data, db_title_arr_n, db_res_arr, qo)
                    except Exception as e:
                        app.logger.error(f'qual_thread_id:{thread_id}; submit_err !!! 再重试最多3次')
                        # 重新发送最多3次
                        for i in range(3):
                            try:
                                qo = submit_qualtrics.get_qsq(send_title_link, wo_topic_id, sleep_time,
                                                              send_random_area)
                                db_title_arr_n = copy.deepcopy(db_title_arr)
                                db_res_arr = json.loads(send_data)
                                submit_data = submit_qualtrics.convert_data_to_submit_data(db_title_arr_n, db_res_arr,
                                                                                           qo, sleep_time)
                                request_res, ip_res = submit_qualtrics.do_submit(submit_data, db_title_arr_n,
                                                                                 db_res_arr, qo)
                                break
                            except Exception as e2:
                                app.logger.error(f'qual_thread_id:{thread_id};submit_err!!!try again,{i} errMsg={e2}')
                                continue
                        if request_res is None:
                            app.logger.error(f'qual_thread_id:{thread_id}; submit_err !!! 完成3次发送重试均失败！')
                            # 更新数据库中该条数据状态为发送失败
                            update_topic_info(cur_topic, -1, cur_topic.submit_start_time, int(time.time()),
                                              cur_topic.request_res, cur_topic.request_ip)
                            raise e
                    app.logger.info(f'qual_thread_id:{thread_id}; Submit ok !!!')
                    request_res_json = json.loads(request_res)
                    request_str = json.dumps(request_res_json['Messages']['EOSMessage']['FinalEOSMessage'])
                elif 'credamo.com' in send_title_link:  # 见数
                    submit_data = submit_credamo.convert_data_to_submit_data(db_title_arr, json.loads(send_data),
                                                                             send_title_link)
                    # app.logger.debug(f'需要提交的答案{submit_data}')
                    request_res, ip_res = submit_credamo.do_submit(send_random_area, send_title_link, submit_data,
                                                                   sleep_time,
                                                                   wo_topic_id)
                    request_str = submit_credamo.get_simple_result(request_res)
                else:  # 默认问卷星
                    submit_data = convert_data_to_submit_data(db_title_arr, json.loads(send_data))
                    # print('需要提交的答案', submit_data)
                    wo_topic_id = '%s_%s' % (str(this_work_order_id), str(data_id))  # 工单和这条数据的id
                    request_res, ip_res = do_submit(send_random_area, send_title_link, submit_data, sleep_time,
                                                    wo_topic_id)
                    request_str = request_res if len(request_res) < 510 else request_res[0:510]
            except Exception as e:
                traceback.print_exc()
                request_str = str(e)[0:510] if e else '请求异常'
            finally:
                t_end = int(time.time())
                if send_title_link.startswith('https://www.wenjuan.com'):  # 问卷网
                    request_res_json = json.loads(request_str)
                    result_code = request_res_json['status']
                    if '200' == result_code:  # status为200表示问卷提交成功
                        new_request_json = dict()
                        new_request_json['code'] = result_code
                        new_request_json['err_msg'] = request_res_json['err_msg']
                        new_request_str = json.dumps(new_request_json)
                        update_topic_info(cur_topic, 2, t_start, t_end, new_request_str, ip_res)
                        # 查询工单是否全部发送完成-发送完成则置为发送成功
                        b_res, status_obj = search_send_status(this_work_order_id)
                        if b_res and status_obj.get('total') == status_obj.get('finished'):
                            work_order_dao.modify_work_order_status(this_work_order_id,
                                                                    WorkOrderStatusEnum.FINISHED.value)
                    pass
                elif send_title_link.startswith('https://wj.qq.com'):  # 腾讯问卷
                    result_code = json.loads(request_str)['code']
                    if 'OK' == result_code:  # code为OK表示问卷提交成功
                        update_topic_info(cur_topic, 2, t_start, t_end, request_str, ip_res)
                        # 查询工单是否全部发送完成-发送完成则置为发送成功
                        b_res, status_obj = search_send_status(this_work_order_id)
                        if b_res and status_obj.get('total') == status_obj.get('finished'):
                            work_order_dao.modify_work_order_status(this_work_order_id,
                                                                    WorkOrderStatusEnum.FINISHED.value)
                elif send_title_link.startswith('https://docs.google.com'):  # 谷歌问卷
                    if 'vHW8K' in request_str:  # 表示问卷提交成功，该标志为“您的回复已记录”的样式
                        update_topic_info(cur_topic, 2, t_start, t_end, request_str, ip_res)
                        # 查询工单是否全部发送完成-发送完成则置为发送成功
                        b_res, status_obj = search_send_status(this_work_order_id)
                        if b_res and status_obj.get('total') == status_obj.get('finished'):
                            work_order_dao.modify_work_order_status(this_work_order_id,
                                                                    WorkOrderStatusEnum.FINISHED.value)
                elif 'qualtrics' in send_title_link:  # qualtrics问卷
                    # 如果request_str内容包含汉字则这里呈现方式为unicode，需要将汉字转化为unicode
                    if 'Your response has been recorded.' in request_str \
                            or chinese_to_unicode('已记录您的回复。') in request_str \
                            or '已记录您的回复。' in request_str:  # 表示问卷提交成功
                        update_topic_info(cur_topic, 2, t_start, t_end, request_str, ip_res)
                        # 查询工单是否全部发送完成-发送完成则置为发送成功
                        b_res, status_obj = search_send_status(this_work_order_id)
                        if b_res and status_obj.get('total') == status_obj.get('finished'):
                            work_order_dao.modify_work_order_status(this_work_order_id,
                                                                    WorkOrderStatusEnum.FINISHED.value)
                elif 'credamo.com' in send_title_link:  # 见数
                    request_res_json = json.loads(request_str)
                    is_success = request_res_json['success']
                    if is_success:  # success为true表示问卷提交成功
                        update_topic_info(cur_topic, 2, t_start, t_end, request_str, ip_res)
                        # 查询工单是否全部发送完成-发送完成则置为发送成功
                        b_res, status_obj = search_send_status(this_work_order_id)
                        if b_res and status_obj.get('total') == status_obj.get('finished'):
                            work_order_dao.modify_work_order_status(this_work_order_id,
                                                                    WorkOrderStatusEnum.FINISHED.value)
                    pass
                else:  # 默认问卷星
                    # 以10开头表示请求成功，另新增结果为{"code":200,"message":"success"}也表示成功，其余的表示请求失败
                    if request_str.startswith('10〒') or '200' in request_str and 'success' in request_str:
                        # 3. 修改这一批次的数据状态为2（发送完成）
                        update_topic_info(cur_topic, 2, t_start, t_end, request_str, ip_res)
                        # 查询工单是否全部发送完成-发送完成则置为发送成功
                        b_res, status_obj = search_send_status(this_work_order_id)
                        if b_res and status_obj.get('total') == status_obj.get('finished'):
                            work_order_dao.modify_work_order_status(this_work_order_id,
                                                                    WorkOrderStatusEnum.FINISHED.value)
                    elif request_str.startswith('9〒'):  # 以9开头表示答案错误
                        update_topic_info(cur_topic, -1, t_start, t_end, request_str, ip_res)
                    elif request_str.startswith('18〒'):  # 以18开头表示问卷题目已被修改，停止所有后续问卷的发送
                        task_stop(work_order_id=this_work_order_id)
                        send_times += 10  # 整个工单停止发送
                    else:
                        update_topic_info(cur_topic, cur_topic.submitted, t_start, t_end, request_str, ip_res)
                        app.logger.info('发送失败，自动重试；重试第' + str(send_times) + '次')
                        # 运行时间
                        resend_time_unix = datetime.datetime.now() + datetime.timedelta(milliseconds=1000)
                        resend_time = resend_time_unix.strftime("%Y-%m-%d %H:%M:%S.%f")  # 生成每组数据的间隔时间(秒)
                        # resend+根据时间戳(ms)作为唯一表示
                        resend_task_id = 'resend' + str(this_work_order_id) + '_child_' + str(int(time.time() * 1000))
                        # 若发送失败，则重新发送
                        send_times += 1
                        scheduler.add_job(send_item, 'date', run_date=resend_time, id=resend_task_id,
                                          jobstore='default',
                                          args=(data_id, sleep_time, db_title_arr, send_title_link,
                                                this_work_order_id, send_random_area, send_times))
        return


def search_send_status(work_order_id: int):
    """
    查询发送状态
    :param work_order_id:
    :return:
    """
    item = work_order_dao.query_work_order_by_id(work_order_id)
    if item is None:
        return False, "工单不存在"
    topics = topic_dao.search_by_work_order_id(work_order_id)
    total = len(topics)
    if total <= 0:
        return False, "没有需要提交的数据"
    finished = 0
    sending = 0
    waiting = 0
    failed = 0
    for i in topics:
        if i.submitted == 0:
            waiting += 1
        elif i.submitted == 1:
            sending += 1
        elif i.submitted == 2:
            finished += 1
        elif i.submitted == -1:
            failed += 1
    res = {'status': item.status, 'total': total, 'finished': finished, 'sending': sending, 'waiting': waiting,
           'failed': failed}
    return True, res


def send_results(work_order_id: int, ids: [], item_answer_start: int, item_answer_end: int, title_link: str,
                 area_value_weight_dict: dict):
    """
    发送数据 - 若开始则不能停止发送
    :param work_order_id: 工单id
    :param ids: 需要处理的数据库id
    :param item_answer_start: 一行数据的答题开始时间
    :param item_answer_end: 一行数据的答题结束时间
    :param title_link: 问卷的链接
    :param area_value_weight_dict: 区域权重的字典
    :return: 发送后的结果数据
    """

    def batch_update_status(data_item_list: [ut.Topic], status: int):
        """

        :param data_item_list:
        :param status:
        :return:
        """
        for cur_i in data_item_list:
            cur_i.submitted = status
        topic_dao.batch_update_by_id(data_item_list)
        return

    with app.app_context():
        # 1。查询这一批次需要的数据
        app.logger.info('本次任务发送数据id:')
        data_items = []
        # print('一共有多少个ids', len(ids))
        for i in ids:
            app.logger.info(i)
            item = topic_dao.search_by_id(i)
            app.logger.info(item)
            if item is not None:
                data_items.append(item)
        if len(data_items) <= 0:  # 数据不存在，无法进行操作
            return
        # 根据数据库数据组装结果数据
        id_data_dict = dict()
        for i in data_items:
            id_data_dict[i.id] = i

        # 查询提交数据与生成数据的映射关系
        wo_extend = work_order_extend_dao.search_by_work_order_id(work_order_id)
        if not wo_extend:
            return
        db_title_arr = wo_extend.title_maps
        # 随机值
        keys = list(area_value_weight_dict.keys())
        weights = list(area_value_weight_dict.values())
        # 2。提交这一批次的数据
        for k in id_data_dict:
            choice_arr = random.choices(keys, weights=weights, k=len(ids))
            if choice_arr:
                random_area = choice_arr[0]
            else:  # 如果生成失败则为全国
                random_area = 'all'
            time.sleep(0.002)  # 睡2毫秒，防止生成相同的task_id
            task_id = str(work_order_id) + '_child_' + str(int(time.time() * 1000))  # 根据时间戳(ms)作为唯一表示
            # print('当前child的task_id:', task_id)
            a = datetime.datetime.now() + datetime.timedelta(milliseconds=100)
            run_time = a.strftime("%Y-%m-%d %H:%M:%S.%f")  # 生成每组数据的间隔时间(秒)
            # print('当前child的每组间隔时间', run_time)
            # 查询基础数据
            # 内部任务立即执行
            random_int = random.randint(item_answer_start, item_answer_end)  # 每行数据生成一个随机数，代表这行数据需要这么多秒后再发送
            scheduler.add_job(send_item, 'date', run_date=run_time, id=task_id, jobstore='default',
                              args=(k, random_int, db_title_arr, title_link, work_order_id, random_area, 0))
        # 3。修改这一批次的数据状态为1（发送中）
        batch_update_status(data_items, 1)
        return


def start_task_wjx(work_order_id, link, send_count_arr, item_answer_start, item_answer_end, interval_start,
                   interval_end, area_value_weight_dict, is_fast_order, can_answer_start, can_answer_end):
    title_link = link
    if is_fast_order:  # 极速提交不受发送时间的限制
        cur_time = datetime.datetime.now() + datetime.timedelta(seconds=1)  # 1秒后开始执行第一个任务
        for i in range(len(send_count_arr)):
            run_time = cur_time.strftime("%Y-%m-%d %H:%M:%S.%f")  # 生成每组数据的间隔时间(秒)
            task_id = str(work_order_id) + '_' + str(run_time)  # 根据时间戳(ms)作为唯一表示
            app.logger.info('每组任务的运行时间：' + run_time)
            # 添加定时任务，并分组
            scheduler.add_job(send_results, 'date', run_date=run_time, id=task_id, jobstore='default', args=(
                work_order_id, send_count_arr[i], item_answer_start, item_answer_end, title_link,
                area_value_weight_dict))
            # 根据 interval_start 和 interval_end生成一个随机时间
            random_int = random.randint(interval_start, interval_end)
            cur_time = cur_time + datetime.timedelta(seconds=random_int)
    else:  # 非急速提交，所有参数均需要处理
        # 1.判断当前时间是否在当天可发送的时间范围内，如果小于可发送时间，则开始时间为当天的发送时间，如果大于可发送时间，则从明天开始发送
        try:
            ymd = datetime.datetime.now().strftime("%Y-%m-%d")  # 当前时间的年月日
            cas_fmt_time = ymd + ' ' + datetime.datetime.fromtimestamp(can_answer_start / 1000).strftime("%H:%M:%S")
            cae_fmt_time = ymd + ' ' + datetime.datetime.fromtimestamp(can_answer_end / 1000).strftime("%H:%M:%S")
            dt_now = datetime.datetime.now()
            dt_cas = datetime.datetime.strptime(cas_fmt_time, '%Y-%m-%d %H:%M:%S')  # 可发送的开始时间
            dt_cae = datetime.datetime.strptime(cae_fmt_time, '%Y-%m-%d %H:%M:%S')  # 可发送的结束时间
            if can_answer_end <= can_answer_start:  # 如果结束时间小于等于开始时间，则结束时间为明天的这个时间
                dt_cae = dt_cae + datetime.timedelta(days=1)
        except Exception as e:
            raise APIException(message="启动发送失败，解析时间错误")
        # 处理开始时间
        start_time = dt_now
        if dt_now < dt_cas:  # 如果小于可发送时间，则开始时间为当天的发送时间
            start_time = dt_cas
            # print('今天预计的时间开发', start_time)
        elif dt_cas < dt_now < dt_cae:
            pass
            # print('此时开始发送', start_time)
        elif dt_now > dt_cae:
            # 如果大于可发送时间，则从明天开始发送
            dt_cas = dt_cas + datetime.timedelta(days=1)
            dt_cae = dt_cae + datetime.timedelta(days=1)
            start_time = dt_cas
            # print('明天开始发送', start_time)
        else:
            # print('其他时间')
            start_time = dt_now
        start_time = start_time + datetime.timedelta(seconds=3) + datetime.timedelta(
            microseconds=random.randint(100000, 999999))  # 3秒后开始执行第一个任务
        for i in range(len(send_count_arr)):
            run_time = start_time.strftime("%Y-%m-%d %H:%M:%S.%f")  # 生成每组数据的间隔时间(秒)
            task_id = str(work_order_id) + '_' + str(run_time)  # 根据时间戳(ms)作为唯一表示
            # print('每组任务的运行时间：', run_time)
            # 添加定时任务，并分组
            app.logger.info('需要发送的数据：')
            app.logger.info(send_count_arr[i])
            try:
                scheduler.add_job(send_results, 'date', run_date=run_time, id=task_id, jobstore='default', args=(
                    work_order_id, send_count_arr[i], item_answer_start, item_answer_end, title_link,
                    area_value_weight_dict))
            except Exception as e:
                app.logger.info('加入任务失败')
                print(e)
            # 根据 interval_start 和 interval_end生成一个随机时间
            random_int = random.randint(interval_start, interval_end)
            start_time = start_time + datetime.timedelta(seconds=random_int)
            if start_time > dt_cae:
                # 可发送时间往后推迟一天，开始日期+1天，结束日期+1天
                dt_cas = dt_cas + datetime.timedelta(days=1) + datetime.timedelta(
                    microseconds=random.randint(100000, 999999))
                dt_cae = dt_cae + datetime.timedelta(days=1)
                start_time = dt_cas  # 下次开始时间设置为明天第一时刻
    return {"title": '定时任务已启动'}


def start_task(work_order_id, link, send_count_arr, item_answer_start, item_answer_end, interval_start,
               interval_end, area_value_weight_dict, is_fast_order, can_answer_start, can_answer_end):
    """启动问卷提交任务（通用）"""
    title_link = link
    if is_fast_order:  # 极速提交不受发送时间的限制
        cur_time = datetime.datetime.now() + datetime.timedelta(seconds=1)  # 1秒后开始执行第一个任务
        for i in range(len(send_count_arr)):
            run_time = cur_time.strftime("%Y-%m-%d %H:%M:%S.%f")  # 生成每组数据的间隔时间(秒)
            task_id = str(work_order_id) + '_' + str(run_time)  # 根据时间戳(ms)作为唯一表示
            app.logger.info('每组任务的运行时间：' + run_time)
            # 添加定时任务，并分组
            scheduler.add_job(send_results, 'date', run_date=run_time, id=task_id, jobstore='default', args=(
                work_order_id, send_count_arr[i], item_answer_start, item_answer_end, title_link,
                area_value_weight_dict))
            # 根据 interval_start 和 interval_end生成一个随机时间
            random_int = random.randint(interval_start, interval_end)
            cur_time = cur_time + datetime.timedelta(seconds=random_int)
    else:  # 非急速提交，所有参数均需要处理
        # 1.判断当前时间是否在当天可发送的时间范围内，如果小于可发送时间，则开始时间为当天的发送时间，如果大于可发送时间，则从明天开始发送
        try:
            ymd = datetime.datetime.now().strftime("%Y-%m-%d")  # 当前时间的年月日
            cas_fmt_time = ymd + ' ' + datetime.datetime.fromtimestamp(can_answer_start / 1000).strftime("%H:%M:%S")
            cae_fmt_time = ymd + ' ' + datetime.datetime.fromtimestamp(can_answer_end / 1000).strftime("%H:%M:%S")
            dt_now = datetime.datetime.now()
            dt_cas = datetime.datetime.strptime(cas_fmt_time, '%Y-%m-%d %H:%M:%S')  # 可发送的开始时间
            dt_cae = datetime.datetime.strptime(cae_fmt_time, '%Y-%m-%d %H:%M:%S')  # 可发送的结束时间
            if can_answer_end <= can_answer_start:  # 如果结束时间小于等于开始时间，则结束时间为明天的这个时间
                dt_cae = dt_cae + datetime.timedelta(days=1)
        except Exception as e:
            raise APIException(message="启动发送失败，解析时间错误")
        # 处理开始时间
        start_time = dt_now
        if dt_now < dt_cas:  # 如果小于可发送时间，则开始时间为当天的发送时间
            start_time = dt_cas
            # print('今天预计的时间开发', start_time)
        elif dt_cas < dt_now < dt_cae:
            pass
            # print('此时开始发送', start_time)
        elif dt_now > dt_cae:
            # 如果大于可发送时间，则从明天开始发送
            dt_cas = dt_cas + datetime.timedelta(days=1)
            dt_cae = dt_cae + datetime.timedelta(days=1)
            start_time = dt_cas
            # print('明天开始发送', start_time)
        else:
            # print('其他时间')
            start_time = dt_now
        start_time = start_time + datetime.timedelta(seconds=3) + datetime.timedelta(
            microseconds=random.randint(100000, 999999))  # 3秒后开始执行第一个任务
        for i in range(len(send_count_arr)):
            run_time = start_time.strftime("%Y-%m-%d %H:%M:%S.%f")  # 生成每组数据的间隔时间(秒)
            task_id = str(work_order_id) + '_' + str(run_time)  # 根据时间戳(ms)作为唯一表示
            # print('每组任务的运行时间：', run_time)
            # 添加定时任务，并分组
            app.logger.info('需要发送的数据：')
            app.logger.info(send_count_arr[i])
            scheduler.add_job(send_results, 'date', run_date=run_time, id=task_id, jobstore='default', args=(
                work_order_id, send_count_arr[i], item_answer_start, item_answer_end, title_link,
                area_value_weight_dict))
            # 根据 interval_start 和 interval_end生成一个随机时间
            random_int = random.randint(interval_start, interval_end)
            start_time = start_time + datetime.timedelta(seconds=random_int)
            if start_time > dt_cae:
                # 可发送时间往后推迟一天，开始日期+1天，结束日期+1天
                dt_cas = dt_cas + datetime.timedelta(days=1) + datetime.timedelta(
                    microseconds=random.randint(100000, 999999))
                dt_cae = dt_cae + datetime.timedelta(days=1)
                start_time = dt_cas  # 下次开始时间设置为明天第一时刻
    return {"title": '定时任务已启动'}


def task_stop(work_order_id):
    """
    通过任务id停止任务进行,
    :param work_order_id:
    :return:
    """
    # 1。工单默认存在
    item = work_order_dao.query_work_order_by_id(work_order_id)
    # 2。查询还未开始运行的定时任务
    jobs = scheduler.get_jobs()
    job_ids = [job.id for job in jobs]
    prefix = str(work_order_id) + '_'
    filtered_strings = list(filter(lambda s: s.startswith(prefix), job_ids))
    app.logger.info('需要删除的定时任务id: ')
    app.logger.info(filtered_strings)
    # 3。删除未运行的定时任务
    for i in filtered_strings:
        scheduler.remove_job(i)
    work_order_dao.modify_work_order_status(item.id, 4)
    return filtered_strings
